package com.kmxd.ams.core.license.verify.model;

import cn.hutool.core.io.FileUtil;
import com.kmxd.ams.core.license.verify.listener.ACustomVerifyListener;
import com.kmxd.ams.license.core.content.LicenseContents;
import com.kmxd.ams.license.core.model.LicenseCustomManager;
import com.kmxd.ams.license.core.model.LicenseExtraParam;
import com.kmxd.ams.license.core.model.LicenseResult;
import com.kmxd.ams.license.core.model.LicenseVerifyParam;
import com.kmxd.ams.license.core.utils.DateUtils;
import de.schlichtherle.license.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Base64Utils;

import java.io.File;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.prefs.Preferences;

/** License校验类 */
@Slf4j
public class LicenseVerifyManager {

  /**
   * 安装License证书
   *
   * @param param License校验类需要的参数
   */
  public synchronized LicenseResult install(LicenseVerifyParam param) {
    LicenseCustomManager licenseManager = null;
    try {
      /* 1、初始化License证书参数 */
      LicenseParam licenseParam = initLicenseParam(param);
      /* 2、创建License证书管理器对象 */
      //          LicenseManager licenseManager =new LicenseManager(licenseParam);
      // 走自定义的Lic管理
      licenseManager = new LicenseCustomManager(licenseParam);
      // base64 转file
      /* 3、获取要安装的证书文件 */
      byte[] bytes = Base64Utils.decodeFromString(param.getLicenseCodeBase64());
      File licenseFile = FileUtil.writeBytes(bytes, param.getLicensePath());
      /* 4、如果之前安装过证书，先卸载之前的证书 == 给null */
      licenseManager.uninstall();
      /* 5、开始安装 */
      LicenseContent content = licenseManager.install(licenseFile);
      LicenseContents.BEGIN_TIME = content.getNotBefore();
      LicenseContents.AFTER_TIME = content.getNotAfter();
      /* 增加业务系统监听，是否自定义验证 */
      LicenseExtraParam licenseCheck = (LicenseExtraParam) content.getExtra();
      LicenseContents.PARAMS = licenseCheck.getParams();
      List<ACustomVerifyListener<?>> customListenerList =
          ACustomVerifyListener.getCustomListenerList();
      for (ACustomVerifyListener<?> listener : customListenerList) {
        listener.install(licenseCheck);
      }
      String message =
          MessageFormat.format(
              "证书安装成功，证书有效期：{0} - {1}",
              DateUtils.date2Str(content.getNotBefore()),
              DateUtils.date2Str(content.getNotAfter()));
      log.debug(message);
      return LicenseResult.success(message, content);
    } catch (Exception e) {
      if (licenseManager != null) {
        try {
          licenseManager.uninstall();
        } catch (Exception exception) {
          exception.printStackTrace();
        }
      }
      log.error(e.getMessage(), e);
      return LicenseResult.error(e.getMessage(), e);
    }
  }

  /**
   * 校验License证书
   *
   * @param param License校验类需要的参数
   */
  public LicenseResult verify(LicenseVerifyParam param) {

    /* 1、初始化License证书参数 */
    LicenseParam licenseParam = initLicenseParam(param);
    /* 2、创建License证书管理器对象 */
    LicenseManager licenseManager = new LicenseCustomManager(licenseParam);
    /* 3、开始校验证书 */
    String message;
    try {
      LicenseContent licenseContent = licenseManager.verify();
      DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      message =
          MessageFormat.format(
              "证书校验通过，证书有效期：{0} - {1}",
              format.format(licenseContent.getNotBefore()),
              format.format(licenseContent.getNotAfter()));
      log.debug(message);
      return LicenseResult.success(message, licenseContent);
    } catch (NoLicenseInstalledException e) {
      message = "证书未安装！";
      log.error(message, e);
      return LicenseResult.error(message, e);
    } catch (LicenseContentException e) {
      log.error(e.getMessage(), e);
      return LicenseResult.error(e.getMessage(), e);
    } catch (Exception e) {
      message = "证书校验失败！";
      log.error(message, e);
      return LicenseResult.error(message, e);
    }
  }

  public void uninstall(LicenseVerifyParam param) throws Exception {
    LicenseParam licenseParam = initLicenseParam(param);
    LicenseManager licenseManager = new LicenseCustomManager(licenseParam);
    licenseManager.uninstall();
    List<ACustomVerifyListener<?>> customListenerList =
        ACustomVerifyListener.getCustomListenerList();
    for (ACustomVerifyListener<?> listener : customListenerList) {
      listener.uninstall();
    }
  }

  public static LicenseResult simpleInstall(LicenseVerifyParam param) {
    LicenseVerifyManager licenseVerifyManager = new LicenseVerifyManager();
    simpleUninstall(param);
    return licenseVerifyManager.install(param);
  }

  public static void simpleUninstall(LicenseVerifyParam param) {
    LicenseVerifyManager licenseVerifyManager = new LicenseVerifyManager();
    try {
      licenseVerifyManager.uninstall(param);
    } catch (Exception e) {
      log.error(e.getMessage(),e);
      // 这里应该不会抛出异常
    }
  }
  /**
   * 初始化证书生成参数
   *
   * @param param License校验类需要的参数
   */
  public static LicenseParam initLicenseParam(LicenseVerifyParam param) {
    Preferences preferences = Preferences.userNodeForPackage(LicenseVerifyManager.class);
    CipherParam cipherParam = new DefaultCipherParam(param.getStorePass());
    KeyStoreParam publicStoreParam =
        new DefaultKeyStoreParam(
            LicenseVerifyManager.class
            /* 公钥库存储路径 */
            ,
            param.getPublicKeysStorePath()
            /* 公匙别名 */
            ,
            param.getPublicAlias()
            /* 公钥库访问密码 */
            ,
            param.getStorePass(),
            null);
    return new DefaultLicenseParam(param.getSubject(), preferences, publicStoreParam, cipherParam);
  }
}
